from django.core.exceptions import ValidationError
from django.shortcuts import render, HttpResponse, redirect
from utils.encrypt import md5
from utils.image_code import check_code
from web import models
from web.forms.account import RegisterModelForm, SendSmsForm, LoginSMSForm,LoginForm
from django.conf import settings
from django.http import JsonResponse
from io import BytesIO ## 图片文件写入内存
from django.db.models import Q
import uuid
import datetime

def register(request):

    if request.method == 'GET':
        form = RegisterModelForm()
        return render(request,'web/register.html',{'form':form})
    form = RegisterModelForm(data=request.POST)
    if form.is_valid():
        # 验证成功将保存一条数据，可以把新增的这条数据赋值给变量instance。即instance中包含着新注册的用户名、密码、手机号等信息。用户的注册数据保存在表userinfo中
        instance = form.save()
        # 免费额度通过中间件中的方式一获取时，需要在交易记录表中创建一条数据
        # 在交易记录表Transaction中创建一条交易记录
        policy_object = models.PricePolicy.objects.filter(category=1, title='个人免费版').first()
        models.Transaction.objects.create(
            status = 2,
            order = str(uuid.uuid4()),
            user = instance,
            price_policy = policy_object,
            count = 0,
            price = 0,
            start_datetime = datetime.datetime.now(),
        )
        return JsonResponse({'status':True,'data':'/web/index/'})
    return JsonResponse({'status':False,'error':form.errors})

def send_sms(request):

    form = SendSmsForm(request,data=request.GET) ## data=request.GET意思是把前端推送过来的数据，传送到类SendSmsForm中进行校验，
        # 实例化的类form中保存校验后的结果和错误信息，因为类SendSmsForm中只定义了一个mobile_phone，所以只能对mobile_phone即手机号进行校验
    # 根据类SendSmsForm中编写的字段可知：传送给类SendSmsForm的数据只能校验手机号码不能为空和格式是否正确
    if form.is_valid():
        # print(7777777777777,form.cleaned_data.get('mobile_phone'))

        return JsonResponse({'status':True,'code':form.cleaned_data.get('mobile_phone')})
    return JsonResponse({'status':False,'error':form.errors})


def register_save(request):

    form = RegisterModelForm(data=request.POST)
    if form.is_valid():

        form.save()
        return redirect('web/register.html')
    return render(request,'web/register.html',{'form':form})

## 短信登陆
def login_sms(request):
    """短信登陆"""
    if request.method == 'GET':
        form = LoginSMSForm()
        return render(request,'web/login_sms.html',{'form':form})
    form = LoginSMSForm(data=request.POST)
    if form.is_valid():
        user_object = form.cleaned_data.get('mobile_phone') ## 利用mobile_phone的钩子方法：return user_object把查询出来的数据对象传递过来
        return JsonResponse({'status': True, 'data': '/web/index/'})
    return JsonResponse({'status': False, 'error': form.errors})

def login(request):
    """用户名和密码登录"""
    if request.method == 'GET':
        form = LoginForm(request)
        return render(request,'web/login.html',{'form':form})
    form = LoginForm(request,data=request.POST) ## 前端页面的数据传给后端的Form或者ModelForm，进行验证处理
    if form.is_valid():

        # user_object = form.cleaned_data.get('username')
        # password = user_object.password
        # pwd = md5(form.cleaned_data.get('password'))
        # code = form.cleaned_data.get('code')
        # if request.session.get('image_code') != code:
        #     form.add_error('code','验证码错误')
        # if pwd != password:
        #     form.add_error('password','用户名或者密码错误')
        # -------------------------------------------------
        username = form.cleaned_data.get('username')
        password = form.cleaned_data.get('password')
        # user_object = models.UserInfo.objects.filter(username=username,password=password).first()
        # 用Q模块进行复杂的查询即：用户名的地方可以输入用户名，也可以输入手机号码，这俩都可以作为登录的用户名进行验证，密码还是进行单独的验证
        user_object = models.UserInfo.objects.filter(Q(username=username)|Q(mobile_phone=username)).filter(password=password).first()
        if user_object:
            """登录成功"""
            # 登录成功，在session中写入user_id=用户的id: user_id:user_object.id
            request.session['user_id'] = user_object.id
            request.session.set_expiry(60*60*24*7) ## 登录成功的记忆时间为7天
            return redirect('/web/index/')
        form.add_error('username','用户名或者密码错误')
        # return render(request,'web/login.html')

    return render(request, 'web/login.html',{'form':form})

def image_code(request):
    image_object,code = check_code()
    ## 把验证码的信息写入到session中,数据格式为：image_code：code，并设置session中这个数据的过期时间为60秒
    request.session['image_code'] = code
    request.session.set_expiry(60)
    # 3. 写入内存(Python3)
    stream = BytesIO()
    image_object.save(stream, 'png')
    image = stream.getvalue()
    return HttpResponse(image)

def logout(request):

    request.session.flush()
    return redirect('index') ## 可以通过别名来找到对应的url
